﻿using LuShanTea.DTO;
using LuShanTea.IService;
using LuShanTea.Service.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LuShanTea.Service
{
    public class PermissionService : IPermissionService
    {
        /// <summary>
        /// 添加权限项
        /// </summary>
        /// <param name="name">权限项名称</param>
        /// <param name="describle">描述</param>
        /// <returns></returns>
        public long AddNew(string name, string describle)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);

                bool isExists = baseService.GetAll().Any(p => p.Name == name);

                if (isExists)
                {
                    throw new ArgumentException("权限项名称：" + name + "已存在");
                }

                Permission permission = new Permission()
                {
                    Name = name,
                    Descible = describle,
                };

                context.Permissions.Add(permission);
                context.SaveChanges();

                return permission.Id;
            }
        }

        /// <summary>
        /// 给角色添加权限项
        /// </summary>
        /// <param name="roleId">角色id</param>
        /// <param name="permissionIds">权限项id</param>
        public void AddPermissionByRole(long roleId, long[] permissionIds)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Role> baseService = new BaseService<Role>(context);

                Role role = baseService.GetById(roleId);

                if (role == null)
                {
                    throw new ArgumentException("角色Id为：" + role.Id + "不存在");
                }

                BaseService<Permission> permissionService = new BaseService<Permission>(context);
                var permissions = permissionService.GetAll()
                    .Where(p => permissionIds.Contains(p.Id));

                foreach (var per in permissions)
                {
                    role.Permissions.Add(per);
                }

                context.SaveChanges();
            }
        }

        /// <summary>
        /// 获取所有权限项
        /// </summary>
        /// <returns></returns>
        public PermissionDTO[] GetAll()
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);
                return baseService.GetAll().ToList()
                    .Select(p => ToDTO(p)).ToArray();
            }
        }


        /// <summary>
        /// 获取管理员权限项
        /// </summary>
        /// <param name="adminUserId">管理员Id</param>
        /// <returns></returns>
        public PermissionDTO[] GetByAdminUserId(long adminUserId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<AdminUser> baseService = new BaseService<AdminUser>(context);

                var adminUser = baseService.GetById(adminUserId);

                if (adminUser == null)
                {
                    throw new ArgumentException("管理员Id为：" + adminUserId + "不存在");
                }

                //每个Role都有一个Permissions属性
                //Roles.SelectMany(r => r.Permissions)就是遍历Roles的每一个Role
                //然后把每个Role的Permissions放到一个集合中
                //IEnumerable<PermissionEntity>
                return adminUser.Roles.SelectMany(r => r.Permissions).ToList()
                    .Select(p => ToDTO(p)).ToArray();
            }
        }

        /// <summary>
        /// 获取权限项
        /// </summary>
        /// <param name="permissionId">权限项Id</param>
        /// <returns></returns>
        public PermissionDTO GetById(long permissionId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);

                var permission = baseService.GetById(permissionId);

                return permission == null ? null : ToDTO(permission);

            }
        }

        /// <summary>
        /// 根据权限项名称获取权限项
        /// </summary>
        /// <param name="permissionName">权限项名称</param>
        /// <returns></returns>
        public PermissionDTO GetByName(string permissionName)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);

                var permission = baseService.GetAll().SingleOrDefault(p => p.Name == permissionName);

                return permission == null ? null : ToDTO(permission);

            }
        }

        /// <summary>
        /// 根据角色Id获取权限项
        /// </summary>
        /// <param name="roleId">角色id</param>
        /// <returns></returns>
        public PermissionDTO[] GetByRoleId(long roleId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Role> baseService = new BaseService<Role>(context);

                return baseService.GetById(roleId).Permissions.ToList()
                    .Select(p => ToDTO(p)).ToArray();

            }
        }

        /// <summary>
        /// 软删除权限项
        /// </summary>
        /// <param name="permissionId"></param>
        public void MarkDeleted(long permissionId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);

                Permission permission = baseService.GetById(permissionId);

                if (permission == null)
                {
                    throw new ArgumentException(string.Format($"订单Id为：{permissionId}不存在"));
                }

                baseService.MakeDelete(permissionId);
            }
        }

        /// <summary>
        /// 更新权限项
        /// </summary>
        /// <param name="permissionId">权限项Id</param>
        /// <param name="name">权限名称</param>
        /// <param name="describle">权限描述</param>
        public void Update(long permissionId, string name, string describle)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Permission> baseService = new BaseService<Permission>(context);

                var permission = baseService.GetById(permissionId);

                if (permission == null)
                {
                    throw new ArgumentException("权限项Id为：" + permissionId + "已存在");
                }

                permission.Name = name;
                permission.Descible = describle;

                context.SaveChanges();

            }
        }

        /// <summary>
        /// 更新角色权限项
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <param name="permissionIds">权限项Id</param>
        public void UpdatePermissionByRoleId(long roleId, long[] permissionIds)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Role> baseService = new BaseService<Role>(context);

                Role role = baseService.GetById(roleId);

                if (role == null)
                {
                    throw new ArgumentException("角色Id为：" + role.Id + "不存在");
                }

                BaseService<Permission> permissionService = new BaseService<Permission>(context);
                var permissions = permissionService.GetAll()
                    .Where(p => permissionIds.Contains(p.Id));

                role.Permissions.Clear();

                foreach (var per in permissions)
                {
                    role.Permissions.Add(per);
                }

                context.SaveChanges();
            }
        }

        private PermissionDTO ToDTO(Permission permission)
        {
            PermissionDTO permissionDTO = new PermissionDTO()
            {
                Name = permission.Name,
                Id = permission.Id,
                Descible = permission.Descible,
                CreateDateTime = permission.CreateDateTime
            };

            return permissionDTO;
        }
    }
}
